package com.fire.interceptor;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.fire.definedAnnotation.Authorization;
import com.fire.util.ConstantKeys;
import com.fire.util.MsgInfo;
import com.fire.util.base.ResultBody;
import com.fire.util.base.TokenUtil;

/**
 * 接口访问权限拦截器，对token进行校验
 * 
 * @author: zoujp
 * @date: 2018年6月1日
 */
@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {

	private final static Logger LOG = Logger.getLogger(AuthorizationInterceptor.class);

	@Autowired
	private TokenUtil tokenUtil;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		Method method = handlerMethod.getMethod();

		boolean result = true;

		if (method.getName().equals("uiConfiguration") || method.getName().equals("swaggerResources")
				|| method.getName().equals("getDocumentation") || method.getName().equals("securityConfiguration")) {
			// 访问Swagger-UI,直接通过
			return true;
		}

		if (null == method.getAnnotation(Authorization.class)) {
			// 如果请求的接口方法无Authorization注解，则需验证token
			String token = request.getHeader(ConstantKeys.REQUEST_HEADER);
			if (token == null) {
				writeResponse(ResultBody.goBack(MsgInfo.z_token_unsign_code, MsgInfo.z_token_unsign_msg), response);
				return false;
			}
			try {
				tokenUtil.verifyJwt(token);
			} catch (TokenExpiredException e) {
				// token过期
				LOG.error("token过期");
				writeResponse(ResultBody.goBack(MsgInfo.z_token_expire_code, MsgInfo.z_token_expire_msg), response);
				result = false;
			} catch (JWTVerificationException e) {
				// token验证失败
				LOG.error("token验证失败");
				writeResponse(ResultBody.goBack(MsgInfo.z_token_unsign_code, MsgInfo.z_token_unsign_msg), response);
				result = false;
			} catch (Exception e) {
				LOG.error("系统内部错误");
				e.printStackTrace();
				writeResponse(ResultBody.goBack(MsgInfo.z_error_code, MsgInfo.z_error_msg), response);
				result = false;
			}
			return result;
		} else {
			// 有Authorization注解，则直接通过
			return true;
		}
	}

	/**
	 * 返回数据进行交互
	 * 
	 * @param o
	 * @param response
	 */
	public void writeResponse(Object o, HttpServletResponse response) {
		String json = "";
		PrintWriter writer = null;
		try {
			response.setContentType("application/json;charset=utf-8");
			response.addHeader("Access-Control-Allow-Origin", "*");

			json = JSONObject.toJSONString(o, SerializerFeature.WriteMapNullValue);

			writer = response.getWriter();
			writer.write(json);
			writer.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (null != writer)
				writer.close();
		}
	}

}
